from __future__ import unicode_literals
import uuid

from django.utils.encoding import python_2_unicode_compatible
from django.conf import settings
from django.db import models

from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

from zanhu02.notifications.views import notification_handler
from zanhu02.users.models import User

@python_2_unicode_compatible
class News(models.Model):
    """动态"""
    uuid_id = models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,null=True,blank=True,
        on_delete=models.SET_NULL,related_name='publisher',verbose_name='用户')
    parent = models.ForeignKey("self",null=True,blank=True,
        on_delete=models.CASCADE,related_name='thread',verbose_name='自关联')
    content = models.TextField(verbose_name='动态内容')
    liked = models.ManyToManyField(User,related_name='liked_news',verbose_name='点赞用户')
    # 值为False时,为动态;值为True时,为评论
    reply = models.BooleanField(default=False,verbose_name='是否为评论')

    created_at = models.DateTimeField(db_index=True,auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '首页'
        verbose_name_plural = verbose_name
        ordering = ['-created_at']

    def __str__(self):
        return self.content

    def switch_like(self, user):
        """点赞与取消赞"""
        # 如果已经赞过,则取消;取出赞过动态的用户,判断是否赞过
        if user in self.liked.all():
            self.liked.remove(user)
        # 如果没赞过,则添加
        else:
            self.liked.add(user)

            # 通知动态的发布者
            notification_handler(user,self.user,'L',self,id_value=str(self.uuid_id),key='social_update')


    def get_parent(self):
        """返回自关联的上级记录或者本身"""
        if self.parent:
            return self.parent
        else:
            return self

    def reply_this(self,user,text):
        """
        回复首页的动态
        :param user: 登录的用户
        :param text: 回复的内容
        :return: None
        """
        parent = self.get_parent()
        News.objects.create(user=user,content=text,
                            reply=True,parent=parent)
        # 通知动态的发布者
        notification_handler(user, parent.user, 'R', parent, id_value=str(parent.uuid_id), key='social_update')

    def get_thread(self):
        """关联到当前记录的所有记录"""
        parent = self.get_parent()
        return parent.thread.all()

    def comment_count(self):
        """评论数"""
        return self.get_thread().count()

    def count_likers(self):
        return self.liked.count()

    def get_likers(self):
        return self.liked.all()
    
    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        super(News, self).save()
        if not self.reply:
            # 如果不是动态的回复
            channel_layer=get_channel_layer()  # 获取频道层
            payload={
                "type": "receive",
                "key": "additional_news",
                "actor_name": self.user.username,
            }
            # 注意此时收到通知的用户应该为  action_object的执行者
            async_to_sync(channel_layer.group_send)('notifications', payload)



